package com.tlgen.coopera.controller;

import com.tlgen.coopera.config.SecurityConfig;
import com.tlgen.coopera.factory.KeypairLocalFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.crypto.Cipher;
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

import static com.tlgen.coopera.factory.AES.encryptUrl;

/*
 *@title HelloController
 *@description
 *@author ta151486
 *@version 1.0
 *@create 2023/12/15 16:13
 */
@RestController
public class HelloController {

    @Autowired
    private SecurityConfig securityConfig;

    @GetMapping("/public-key")
    public Object getRsa() {
        String publicKey = Base64.getEncoder().encodeToString(securityConfig.getKeyPair().getPublic().getEncoded());
        String privateKey = Base64.getEncoder().encodeToString(securityConfig.getKeyPair().getPrivate().getEncoded());
        Map<String, String> map = new HashMap<>();
        map.put("publicKey", publicKey);
        map.put("privateKey", privateKey);
        return map;
    }

    /**
     * 这里模拟前端使用公钥进行加密(正确应该是由前端工具类进行生成加密后的，前端把加密后的进行上送到后端进行保存),
     * 这里的 symmetricKey 不应该直接上送，每一次调用一次保存
     * 而是由前端进行加密后上送密文到后端，后端使用私钥进行解密获取该对称密钥
     * @return
     */
    @GetMapping("/rsa")
    public String rsa() {
        try {
            String publicKeyPEM = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnCIzvBrlXF9ReWZicus+ti8ZINSGQl9CSdKD4yLpDbraYgE9knsrXuVLLh25BE1Qz48NYdzFz/XjWOh/u/6SHmp3uAn0m4iAVvm6Wq9mfz8tfjBIxdJWIIJY7crsGbNXJb4XCBtR8omERmEkBkhyszyz0ZrX6dOnz25Eakc+hk8Zpixg/0giAELw5aIQxjgN1vLTxfoRVoy/T/I4yvyseTHEr7tBjKX2zW4eBB9xgvylvX0R+wKHZS8UiEpZwat12JinPI2Ndpdr3Sh1arqpSk4Ojk578HX6SHb6MYHzdjnMBEJ2ZXXHkUr/VYb6d0FaOiwCjbUjIXSMjgoxpdaSQwIDAQAB";

            // Replace with your symmetric key
            String symmetricKey = "abcdefghijkl1234";

            // Converting PEM to PublicKey
            byte[] decoded = Base64.getDecoder().decode(publicKeyPEM);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoded);
            PublicKey publicKey = keyFactory.generatePublic(keySpec);

            // Encrypting symmetric key
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encryptedSymmetricKey = cipher.doFinal(symmetricKey.getBytes());
            String encryptedSymmetricKeyBase64 = Base64.getEncoder().encodeToString(encryptedSymmetricKey);

            // 存到 redis, 后端使用私钥进行解密获取对称密钥, 将对称密钥存入 redis

            // Printing encrypted symmetric key
            System.out.println(encryptedSymmetricKeyBase64);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return "SUCCESS";
    }


    @GetMapping("/aes")
    public String aes() {
        try {
            String plaintext = "productId=1";
            //String plaintext = "productId=1&signature=wHYOLLkTn00DVrcmuCFzFQ==";
            //密钥必须是64位,即八个字节,我这边是只有4个字节,所以就出现异常了
            String symmetricKey = "abcdefghijkl1234";  // Ensure this key has 16 bytes

            String encryptedText = encryptUrl(plaintext, symmetricKey);
            System.out.println(encryptedText);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return "SUCCESS";
    }

    @GetMapping("/aesSignature")
    public String aesSignature() {
        try {
            String plaintext = "productId=1&signature=nloU6arPmk1iYH5fce1f5g==";
            //String plaintext = "productId=1&signature=wHYOLLkTn00DVrcmuCFzFQ==";
            //密钥必须是64位,即八个字节,我这边是只有4个字节,所以就出现异常了
            String symmetricKey = "abcdefghijkl1234";  // Ensure this key has 16 bytes

            String encryptedText = encryptUrl(plaintext, symmetricKey);
            System.out.println(encryptedText);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return "SUCCESS";
    }

    @GetMapping("/request")
    public String request(HttpServletRequest request) {
        String encryptedSymmetricKey = String.valueOf(request.getHeaders("X-Encrypted-Symmetric-Key"));
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, securityConfig.getKeyPair().getPrivate());
            byte[] decryptedKeyBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedSymmetricKey));
            //得到对称密钥
            String symmetricKey = new String(decryptedKeyBytes, StandardCharsets.UTF_8);
            String redisSymmetricKey = "symmetric:key:" + 1;
//            stringRedisTemplate.opsForValue().set(redisSymmetricKey, symmetricKey);
            KeypairLocalFactory.getInstance().setSymmetrickey(redisSymmetricKey);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "SUCCESS";
    }

}
